﻿using PluginForCertHandOut;
using PluginForDNSRecord;
using System.Reflection;
namespace Service
{
    public class PluginFactory
    {
        static List<string> pluginDNSRecoredEditorPaths;
        static List<string> pluginComputerServerPaths;
        static PluginFactory()
        {
            pluginDNSRecoredEditorPaths = GetPluginDllPath("DNSRecoredEditor");
            pluginComputerServerPaths = GetPluginDllPath("CertHandOut");
            if (pluginDNSRecoredEditorPaths.Count < 1 || pluginComputerServerPaths.Count < 1)
            {
                throw new Exception("请至少保留一个插件");
            }
            //将所有的插件加载到内存
            foreach (var item in pluginComputerServerPaths.Union(pluginDNSRecoredEditorPaths))
            {
                LoadPlugin(item);
            }
        }
        static List<string> GetPluginDllPath(string PluginName)
        {
            if (!Directory.Exists(Path.Join("Plugin", PluginName)))
            {
                Directory.CreateDirectory(Path.Join("Plugin", PluginName));
                throw new Exception("请在Plugin/DNSRecoredEditor 和Plugin/CertHandOut 目录中放入插件,至少需要一个。");
            }
            var dirs = Directory.EnumerateDirectories(Path.Join("Plugin", PluginName));
            var pluginPaths = new List<string>();
            foreach (var dir in dirs)
            {
                DirectoryInfo item = new DirectoryInfo(dir);
                var pluginLocation = Path.Join(item.FullName, $"{item.Name}.dll");
                pluginPaths.Add(pluginLocation);
            }
            return pluginPaths;
            
        }
        static Assembly LoadPlugin(string pluginLocation)
        {
            PluginLoadContext loadContext = new PluginLoadContext(pluginLocation);
            return loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation)));
        }
        /// <summary>
        /// 创建 DNSRecordEditor实例
        /// </summary>
        /// <returns></returns>
        public static List<IDNSRecordEditor> CreateDNSRecordEditorInstance()
        {
            var _assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(o => pluginDNSRecoredEditorPaths.Contains(o.Location));
            var results = new List<IDNSRecordEditor>();
            foreach (var assembly in _assemblies)
            {
                foreach (Type type in assembly.GetTypes())
                {
                    if (typeof(IDNSRecordEditor).IsAssignableFrom(type))
                    {
                        IDNSRecordEditor result = Activator.CreateInstance(type) as IDNSRecordEditor;
                        if (result != null)
                        {
                            results.Add(result);
                        }
                    }
                }
            }
            return results;
        }

        /// <summary>
        /// 创建 DNSRecordEditor实例
        /// </summary>
        /// <returns></returns>
        public static List<ICertHandOut> CreateCertHandOutInstance()
        {
            var _assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(o => pluginComputerServerPaths.Contains(o.Location));
            var results = new List<ICertHandOut>();
            foreach (var assembly in _assemblies)
            {
                foreach (Type type in assembly.GetTypes())
                {
                    if (typeof(ICertHandOut).IsAssignableFrom(type))
                    {
                        ICertHandOut result = Activator.CreateInstance(type) as ICertHandOut;
                        if (result != null)
                        {
                            results.Add(result);
                        }
                    }
                }
            }
            return results;
        }
    }
}
